package com.neusoft.elmboot.service.impl;

import com.neusoft.elmboot.dto.UserDTO;
import com.neusoft.elmboot.dto.UserPrivacyDTO;
import com.neusoft.elmboot.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.neusoft.elmboot.mapper.UserMapper;
import com.neusoft.elmboot.po.User;
import com.neusoft.elmboot.service.UserService;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService{
	
	@Autowired
	private UserMapper userMapper;

	@Override
	public User userRegister(User user) {

		String userId = user.getUserId();

		//调用findByUsername(username) 判断用户是否被注册过
		User result = userMapper.findByUserId(userId);
		if(result != null){
			throw new UserDuplicationException("该ID已被注册！请重新输入!");
		}

		//密码加密MD5
		//串+password+串 ---- md5算法加密，连续加载3次  串：盐值
		String oldPassword = user.getPassword();
		//获取盐值（成一个随机的、唯一的字符串（盐值），并将其转换为大写）
		String salt = UUID.randomUUID().toString().toUpperCase();
		//补全数据：盐值的记录
		user.setSalt(salt);
		//将密码和盐值作为一个整体进行加密处理
		//这个方法将原始密码和盐值连接在一起，然后进行三次MD5加密，最后返回加密后的密码。
		String md5Password = getMD5Password(oldPassword, salt);
		//将加密的密码重新补全到User对象中
		user.setPassword(md5Password);

		int data = userMapper.insert(user);
		if(data != 1) {
			throw new InsertException("注册失败!");
		}
		return user;
	}

	//用户登录
	@Override
	public User userLogin(String userId,String password) {
		User result = userMapper.findByUserId(userId);
		if (result == null) {
			throw new DataNotFoundException("用户不存在!");
		}
		//1.先获取到数据库中的加密之后密码
		String oldPassword = result.getPassword();
		//2.和用户传递过来的密码进行比较
		//2.1先获取盐值
		String salt = result.getSalt();
		//2.2 将用户的密码按照相同的md5算法的规则进行加密
		String newMd5Password = getMD5Password(password, salt);
		//3.密码进行比较
		if (!oldPassword.equals(newMd5Password)) {
			throw new PasswordNotMatch("密码错误!请重新输入！");
		}
		//4.判断用户是否被删除
		if (result.getDelTag() == 0) {
			throw new DataNotFoundException("用户已被删除！");
		}
		User user = new User();
		user.setUserId(result.getUserId());
		user.setUserName(result.getUserName());
		user.setUserSex(result.getUserSex());

		return user;
	}
	
	@Override
	public User getUserById(String userId) {
		User result = userMapper.findByUserId(userId);
		if (result == null) {
			throw new DataNotFoundException("用户不存在!");
		}
		return result;
	}

	@Override
	public UserDTO changeUserInfo(UserDTO user) {
		if(userMapper.getUserById(user.getUserId()) == null) {
			throw new DataNotFoundException(" 该用户不存在!");
		}
		int data = userMapper.changeUserInfo(user);
		if (data <= 0) {
			throw new UpdateException("修改用户信息失败!");
		}
		return user;
	}
	public static final int AVATAR_MAX_SIZE = 10 * 1024 *1024;
	public static final List<String> AVATAR_TYPE = new ArrayList<>();
	static {
		AVATAR_TYPE.add("images/jpeg");
		AVATAR_TYPE.add("images/png");
		AVATAR_TYPE.add("images/bmp");
		AVATAR_TYPE.add("images/gif");
		AVATAR_TYPE.add("images/jpg");
	}
	@Override
	public int changeAvatar(String userId, MultipartFile file) throws IOException {
		if (file.isEmpty()) {
			throw new FileException("上传的文件为空!");
		}
		if (file.getSize() > AVATAR_MAX_SIZE){
			throw new FileException("文件超出限制！");
		}
		String contentType = file.getContentType();
		if (!AVATAR_TYPE.contains(contentType)) {
			throw new FileException("文件类型不支持！");
		}
		String fileName = file.getOriginalFilename();
		//表示保存上传的文件的目录路径
		String filePath = "E:/upload/";


		//表示上传文件在服务器上的存储位置
		File dest = new File(Paths.get(filePath, fileName).toString());
		//将上传的文件保存到dest表示的位置。
		file.transferTo(dest);
		String fileUrl = "E:/upload/" + fileName;
		User user = userMapper.getUserById(userId);
		user.setUserImg(fileUrl);
		int result = userMapper.changeAvatar(user);
		if (result <= 0) {
			throw new UpdateException("修改用户头像失败!");
		}
		return result;
	}

	@Override
	public int changePassword(UserPrivacyDTO userPrivacyDTO) {
		User data = userMapper.findByUserId(userPrivacyDTO.getUserId());
		if (data == null) {
			throw new DataNotFoundException("该用户不存在!");
		}
		String oldPassword = userPrivacyDTO.getOldPassword();
		String newPassword = userPrivacyDTO.getNewPassword();
		String confirmNewPassword = userPrivacyDTO.getConfirmNewPassword();
		if (!newPassword.equals(confirmNewPassword)) {
			throw new PasswordNotMatch("两次输入的新密码不匹配!请重新输入！");
		}
		String salt = data.getSalt();
		String oldMd5Password = getMD5Password(oldPassword, salt);
		if (!oldMd5Password.equals(data.getPassword())) {
			throw new PasswordNotMatch("原密码错误!请重新输入！");
		}
		String newMd5Password = getMD5Password(newPassword, salt);
		if (oldMd5Password.equals(newMd5Password)) {
			throw new PasswordNotMatch("新密码不能与旧密码相同!请重新输入！");
		}
		int result = userMapper.changePassword(userPrivacyDTO.getUserId(), newMd5Password);
		if (result <= 0) {
			throw new UpdateException("修改密码失败!");
		}
		return result;
	}









	private String getMD5Password(String password, String salt){
		for (int i = 0; i < 3; i++) {
			password = DigestUtils.md5DigestAsHex((salt+password+salt).getBytes()).toUpperCase();
		}
		return password;
	}

}
